//
//  FancyItemsViewController.swift
//  Fancyswap
//
//  Created by Francois Gratton on 2015-03-07.
//  Copyright (c) 2015 Jonathan Muschalle. All rights reserved.
//

import Foundation
import UIKit

let reuseIdentifier = "FancyItemListCell"

class FancyItemsViewController: UICollectionViewController,FancyViewControllerProtocol {

    var itemList = [FancyItem]()
    let fancyApi  = FancyRestApi()
    let refreshCtrl = UIRefreshControl()
    var currViewPage: Int = 0
    var expectedFetchCount: Int = 0
    var AllItemsLoaded: Bool = false
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // pull down to refresh
        refreshCtrl.tintColor = UIColor.grayColor()
        refreshCtrl.addTarget(self, action: "pullRefresh", forControlEvents: .ValueChanged)
        collectionView?.addSubview(refreshCtrl)
        collectionView?.alwaysBounceVertical = true

        loadItems()
    }

    override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as FancyItemCell
    
        // early fetch next page when scroll reached the limit threashold (remains less than half a page)
        if !AllItemsLoaded && (itemList.count - indexPath.row + expectedFetchCount) <= (fancyApi.GetItemsPerPage() / 2)
        {
            loadItems(append: true)
        }
        
        let fancyItem = itemAtIndexPath(indexPath)
        
        // use image if cached, else show loading and fetch image in back
        if fancyItem.thumbnail != nil
        {
            cell.Thumbnail.image = fancyItem.thumbnail
            cell.Loading.hidden = true
            cell.activitySpinner.stopAnimating()
            cell.lblError.hidden = true
        }
        else
        {
            cell.Thumbnail.image = nil
            cell.Loading.hidden = false
            cell.activitySpinner.startAnimating()
            cell.activitySpinner.hidden=false
            cell.lblError.hidden = true

            let url = fancyApi.imageURL(fancyItem.image, size: ImageFormat.Thumbnail)

            fancyApi.GetDataFromUrl (url) {
                srcUrl, succeeded, msg, data in
                let filename = srcUrl.lastPathComponent
                let nsndx = self.IndexFromItemName(filename)
                if nsndx.row == -1 {
                    return
                }
                let _cell = self.collectionView?.cellForItemAtIndexPath(nsndx)
                
                if succeeded
                {
                    // set and cache fetched image
                    let img = UIImage(data: data!)
                    let fItem = self.itemAtIndexPath(nsndx)
                    fItem.thumbnail = img

                    if _cell != nil
                    {
                        let loadingCell = _cell as FancyItemCell
                        
                        loadingCell.Loading.hidden = true
                        loadingCell.activitySpinner.stopAnimating()
                        loadingCell.Thumbnail.image = img
                        loadingCell.lblError.hidden = true
                    }
                }
                else
                {
                    if _cell != nil
                    {
                        let loadingCell = _cell as FancyItemCell
                        loadingCell.Loading.hidden = true
                        loadingCell.activitySpinner.stopAnimating()
                        loadingCell.lblError.hidden = false
                    }
                }
            }

        }
        cell.Name.text = fancyItem.name
        cell.marque.text = fancyItem.brand
        cell.taille.text = "Taille: \(fancyItem.size)"
        cell.prix.text = String(fancyItem.value)
        
        return cell
    }
    
    ///Method to refresh item list or fetch the next page and append the elements to the list
    ///
    ///:param: append Flag to append the next page or reload the list
    func loadItems(append: Bool = false)
    {
        if append == true
        {
            expectedFetchCount = expectedFetchCount + fancyApi.GetItemsPerPage()
        }
        else
        {
            itemList.removeAll(keepCapacity: false)

            AllItemsLoaded = false
            currViewPage = 0
            expectedFetchCount = 0
        }
        for i in 1...fancyApi.GetItemsPerPage()
        {
            itemList.append(FancyItem())
        }
        currViewPage++
        
        fancyApi.GetItemList(currViewPage-1) {
            pageIndex, succeeded, msg, items in
            if succeeded
            {
                if pageIndex > 0
                {
                    self.expectedFetchCount = self.expectedFetchCount - self.fancyApi.GetItemsPerPage()
                }
                
                if items!.count == 0
                {
                    self.AllItemsLoaded = true
                    for i in 0 ... (self.fancyApi.GetItemsPerPage() - 1)
                    {
                        self.itemList.removeLast()
                    }
                }
                else
                {
                    let offset = pageIndex * self.fancyApi.GetItemsPerPage()

                    for i in  0...(items!.count-1)
                    {
                        self.itemList[offset + i] = items![i]
                    }
                    if( items!.count < self.fancyApi.GetItemsPerPage())
                    {
                        for i in 0 ... (self.fancyApi.GetItemsPerPage() - items!.count)
                        {
                            self.itemList.removeLast()
                        }
                    }
                }
                
                self.collectionView?.reloadData()
            }
            else
            {
                self.showMessage("Incapable de se connecter au serveur, SVP essayez plus tard.", title: "Liste des Items")
            }
            
            if self.refreshCtrl.refreshing == true
            {
                self.refreshCtrl.endRefreshing()
            }
        }
        
    }
    
    /// remove all pages but 1st one, then refetch
    func pullRefresh() {
        
        if itemList.count > fancyApi.GetItemsPerPage()
        {
            itemList.removeRange(fancyApi.GetItemsPerPage()...itemList.count-1)
            collectionView?.reloadData()
        }
        
        
        loadItems()
        
    }
    
    ///Show message box with ok button
    func showMessage(msg: String, title: String)
    {
        let alert = UIAlertController(title: title, message: msg, preferredStyle: UIAlertControllerStyle.ActionSheet)
        alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler:
            {
                action -> Void in
                println("OK")
            }
        ))

        presentViewController(alert, animated: true) { () -> Void in }

    }
    
    override func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
        return 1
    }
    override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return itemList.count
    }
    
    func itemAtIndexPath(indexPath: NSIndexPath) -> FancyItem {
        return itemList[indexPath.row]
    }
    func IndexFromItemName(filename: String) -> NSIndexPath {
        for i in 0...(itemList.count-1)
        {
            if itemList[i].image.caseInsensitiveCompare(filename) == NSComparisonResult.OrderedSame {
                return NSIndexPath(forRow: i, inSection: 0)
            }
        }
        return NSIndexPath(forRow: -1, inSection: 0)
    }
    
    ///clean up cached images of items not visible, +-5 items.
    ///remove thumbnail and list of images used in detail view.
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // phase 2: clear some UIImage from itemList
        
        var visibleNdxs = collectionView?.indexPathsForVisibleItems() as [NSIndexPath]
        
        if visibleNdxs.count == itemList.count {
            return
        }

        visibleNdxs.sort({$0.row > $1.row})
        let loIndex = visibleNdxs[0].row - 5
        let hiIndex = visibleNdxs[visibleNdxs.count-1].row + 5
        
        for i in 0...(itemList.count - 1)
        {
            if i < loIndex || i > hiIndex
            {
                itemList[i].thumbnail = nil
                itemList[i].imageFiles.removeAll(keepCapacity: false)
                itemList[i].thumbs.removeAll(keepCapacity: false)
            }
        }
    }
    
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

        if segue.identifier == "showDetails" {
            let cell = sender as UICollectionViewCell
            let indexPath = collectionView?.indexPathForCell(cell)
            
            var item = itemAtIndexPath(indexPath!)
            
            let detailView = segue.destinationViewController as FancyDetailsController
            detailView.item = item
            detailView.dismissDelegate = self
        }
        
    }
    
    ///delegate function called by the detail controler after a successful order.
    ///will 
    func dismissViewControllerAndTakeAction(sender:UIViewController)
    {
        let detailView = sender as FancyDetailsController
        if detailView.ordered
        {
            let item = detailView.item!
            let ndx = IndexFromItemName(item.image)
            itemList.removeAtIndex(ndx.row)
            collectionView?.reloadData()
        }
        sender.navigationController?.popViewControllerAnimated(false)

    }

    @IBAction func home(sender: AnyObject) {
        self.dismissViewControllerAnimated(true, completion: nil)
    }
}
